<template>
  <div class="schedule-box">
    <div class="breadcrumb">
      <a-breadcrumb>
        <a-breadcrumb-item>
          <a @click="toIndex">首页</a>
        </a-breadcrumb-item>
        <a-breadcrumb-item>
          <a @click="goNext">设备列表</a>
        </a-breadcrumb-item>
        <a-breadcrumb-item>
          <a>发布日程</a>
        </a-breadcrumb-item>
      </a-breadcrumb>
    </div>
    <div class="schedule">
      <Card>
        <div class="schedule-flex">
          <!-- 日期面板 -->
          <div class="schedule-time">
            <Calendar
              v-model:value="dataTime"
              value-format="YYYY-MM-DD"
              :fullscreen="false"
              :disabled-date="disabledDate"
              @change="dateChange"
            >
              <template #headerRender="{ value: current, onChange }">
                <!-- 头部样式 -->
                <div style="padding: 10px">
                  <div style="display: flex; align-items: center; justify-content: space-between">
                    <!-- 左侧箭头 -->
                    <div style="display: flex">
                      <a-button
                        type="text"
                        size="small"
                        :disabled="isToday"
                        @click="
                          () => {
                            onChange(current.year(current.year() - 1));
                          }
                        "
                      >
                        <DoubleLeftOutlined />
                      </a-button>
                      <a-button
                        type="text"
                        size="small"
                        :disabled="isToday"
                        @click="
                          () => {
                            onChange(current.month(parseInt(current.month() - 1, 10)));
                          }
                        "
                      >
                        <LeftOutlined />
                      </a-button>
                    </div>
                    <!-- 中间标题内容 -->
                    <div class="header-title">
                      {{ `${current.year()}年${current.month() + 1}月` }}
                    </div>
                    <!-- 右侧箭头 -->
                    <div style="display: flex">
                      <a-button
                        type="text"
                        size="small"
                        @click="
                          () => {
                            onChange(current.month(parseInt(current.month() + 1, 10)));
                          }
                        "
                      >
                        <RightOutlined />
                      </a-button>
                      <a-button
                        type="text"
                        size="small"
                        @click="
                          () => {
                            onChange(current.year(current.year() + 1));
                          }
                        "
                      >
                        <DoubleRightOutlined />
                      </a-button>
                    </div>
                  </div>
                </div>
              </template>
            </Calendar>
          </div>
          <div class="gantt-chart">
            <div class="title-top">
              <div class="icon-arrow">
                <i
                  :class="[
                    'ifont-wid-Calendar_icon_month_left',
                    { 'ifont-wid-Calendar_icon_month_left--disabled': isToday }
                  ]"
                  :disabled="isToday"
                  @click="dateReduce"
                />
                <i class="ifont-wid-Calendar_icon_month_right" @click="datePlus" />
              </div>
              <span class="header-title">{{ dataTime }}{{ isToday ? '今天' : '' }}</span>
              <span style="color: #c2c2c2; margin-left: 16px">
                <!-- 注：灰色块是被其他信息发布覆盖的时间，该时间内不会发布本条信息 -->
              </span>
            </div>
            <div v-if="dataList.length === 0" class="no-list">
              <Empty :image="simpleImage" />
            </div>
            <div class="right-gantt">
              <div
                id="ganttChart"
                ref="ganttCharts"
                :style="{ width: '100%', height: '350px' }"
              ></div>

              <div class="legend">
                <div v-for="(item, legendIndex) in legendList" :key="legendIndex" class="boxs">
                  <Popover
                    placement="top"
                    style="margin-bottom: 15px"
                    :get-popup-container="
                      triggerNode => {
                        return triggerNode.parentNode || document.body;
                      }
                    "
                  >
                    <template #content>
                      <div>
                        <div>{{ item.realPerson }}</div>
                        <div>{{ item.releaseRealName }}</div>
                      </div>
                    </template>
                    <!--图例中的真实数据-->
                    <div class="color" :style="{ background: item.color }"></div>
                    <div class="content">
                      <div class="person">{{ item.person }}</div>
                      <div class="release-name">{{ item.releaseName }}</div>
                    </div>
                  </Popover>
                </div>
              </div>
            </div>
          </div>
        </div>
      </Card>
    </div>
  </div>
</template>
<script setup>
import { Card, Calendar, Popover, Empty } from 'ant-design-vue';
import * as echarts from 'echarts';
import {
  DoubleLeftOutlined,
  LeftOutlined,
  RightOutlined,
  DoubleRightOutlined
} from '@ant-design/icons-vue';
import { ref, onMounted, computed } from 'vue';
import { formatDate } from '@/util/formatDate';
import { releaseSchedule } from '@/api/user';
import { useRoute, useRouter } from 'vue-router';

const route = useRoute();
const router = useRouter();
const simpleImage = ref(require('@/assets/images/noData@2x.png'));
function toIndex() {
  router.push({
    path: '/'
  });
}
function goNext() {
  router.push({
    path: '/service/devices'
  });
}

const dataTime = ref(formatDate(new Date()));
const isToday = computed(() => {
  return dataTime.value <= formatDate(new Date());
});

const legendList = ref([]);
function disabledDate(date) {
  return new Date(date) <= new Date() - 24 * 60 * 60 * 1000;
}
// echarts图上的日期
function datePlus() {
  let plusDate = new Date(new Date(dataTime.value).getTime() + 24 * 60 * 60 * 1000);
  dataTime.value = formatDate(plusDate);
  getEcharts();
}
function dateReduce() {
  if (isToday.value) {
    return;
  }
  let reduceDate = new Date(new Date(dataTime.value).getTime() - 24 * 60 * 60 * 1000);
  dataTime.value = formatDate(reduceDate);
  getEcharts();
}

function dateChange() {
  getEcharts();
}

let ganttChart = null;
let ganttCharts = ref(null);
function initCharts(resData) {
  // 1.实例化对象
  if (!ganttChart) {
    ganttChart = echarts.init(ganttCharts.value);
  }
  // y轴标题

  // 一天
  let dayTime = 3600 * 24 * 1000;
  let nowDate = new Date(); // 当前时间
  // 返回日期格式 2022-01-07
  let nowDateStr = formatDate(nowDate);
  function formatDate(date) {
    // 将2020/2/3这种日期格式，转换为2020-02-03
    let arr = date.toLocaleDateString().split('/');
    if (arr[1].length < 2) {
      // 对月份进行处理：如果月份的长度为1，则拼接上字符串0
      arr.splice(1, 1, '0' + arr[1]);
    }
    if (arr[2].length < 2) {
      // 对天数进行处理：如果天数的长度为2，则拼接上字符串0
      arr.splice(2, 1, '0' + arr[2]);
    }
    return arr.join('-');
  }

  const categories = [];
  const data = [];
  function color() {
    let str = '#';
    let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'];
    for (let i = 0; i < 6; i++) {
      let num = parseInt(Math.random() * 16); // 随机产⽣0-15之间的⼀个数
      str += arr[num]; // 产⽣的每个随机数都是⼀个索引,根据索引找到数组中对应的值,拼接到⼀起
    }
    return str;
  }
  function quchong(dataList, id) {
    let res = []; // 去重复后的集合
    let tem = {};
    for (let i = 0; i < dataList.length; i++) {
      if (!tem[dataList[i][id]]) {
        res.push(dataList[i]);
        tem[dataList[i][id]] = 1;
      }
    }
    return res;
  }
  resData.forEach((item, index) => {
    categories.push(`优先级${index + 1}`);
    const nameObj = {
      0: '普通发布',
      1: '定时按天发布',
      2: '定时按周发布'
    };
    // 发布时机类型为0的话，全天进行渲染，为1或2的话只渲染后台返回的时段
    if (item.releaseOpportunityType === 0) {
      const obj = {
        name: '优先级' + (index + 1),
        value: [index],
        id: item.id,
        releaseUserName: item.releaseUserName ? item.releaseUserName : '暂无', // 发布人姓名
        infoName: item.infoName, // 发布信息的名称
        itemStyle: {
          color: color()
        },
        releaseOpportunityType: nameObj[+item.releaseOpportunityType]
      };
      obj.value.push(`${dataTime.value} 00:00`, `${dataTime.value} 24:00`);
      // obj.value.push(item.validPeriodStart + ' 00:00', item.validPeriodStop + ' 24:00');
      data.push(obj);
    } else {
      if (item.infoTimingList.length && item.infoTimingList) {
        item.infoTimingList.forEach((timeItem, timeIndex) => {
          const tmpObj = {
            name: '优先级' + (index + 1),
            value: [index],
            id: item.id,
            releaseUserName: item.releaseUserName ? item.releaseUserName : '暂无', // 发布人姓名
            infoName: item.infoName, // 发布信息的名称
            releaseOpportunityType: nameObj[item.releaseOpportunityType], // 发布时机类型
            itemStyle: {
              color: color()
            }
          };
          tmpObj.value.push(
            `${dataTime.value} ${timeItem.timingPartStart.slice(0, 5)}`,
            `${dataTime.value} ${timeItem.timingPartStop.slice(0, 5)}`
            // `${dataTime.value} 08:00`,
            // `${dataTime.value} 10:00`,
            // `${dataTime.value} 12:00`,
            // `${dataTime.value} 14:00`
          );
          data.push(tmpObj);
        });
        // } else if (!item.infoTimingList.length) {
        const obj = {
          name: '优先级' + (index + 1),
          value: [index],
          id: item.id,
          releaseUserName: item.releaseUserName ? item.releaseUserName : '暂无', // 发布人姓名
          infoName: item.infoName, // 发布信息的名称
          releaseOpportunityType: nameObj[item.releaseOpportunityType], // 发布时机类型
          itemStyle: {
            color: color()
          }
        };
        data.push(obj);
      }
    }
    for (let index = 0; index < data.length; index++) {
      let names = data[index];
      for (let j = 0; j < data.length; j++) {
        if (data[j].name === names.name) {
          data[j].itemStyle.color = names.itemStyle.color;
        }
      }
    }
  });
  function isIntersect(arr1, arr2) {
    let start = [Math.min(...arr1), Math.min(...arr2)]; // 区间的两个最小值
    let end = [Math.max(...arr1), Math.max(...arr2)]; // 区间的两个最大值
    return Math.max(...start) <= Math.min(...end); // 最大值里的最小值 是否 小于等于 最大值的最小值
  }
  //   图例中的数据
  const arr = [];
  data.forEach(item => {
    const obj = {
      id: item.id,
      person: item.releaseUserName.replace(/^(.{6}).+$/, '$1...'), // 截取字符串
      realPerson: item.releaseUserName,
      releaseName: item.infoName.replace(/^(.{10}).+$/, '$1...'),
      releaseRealName: item.infoName
    };
    if (item.itemStyle) {
      obj.color = item.itemStyle.color;
    } else {
      obj.color = 'rgb(84, 112, 198)'; // 设置默认颜色
    }
    arr.push(obj);
  });
  legendList.value = quchong(arr, 'id');
  // 在渲染时，data中的每个数据项都会调用这个方法
  function renderItem(params, api) {
    const categoryIndex = api.value(0);
    const start = api.coord([api.value(1), categoryIndex]);
    const end = api.coord([api.value(2), categoryIndex]);
    const height = api.size([0, 1])[1] * 0.6;
    const rectShape = echarts.graphic.clipRectByRect(
      {
        x: start[0],
        y: start[1] - height / 2,
        width: end[0] - start[0],
        height: height
      },
      {
        x: params.coordSys.x,
        y: params.coordSys.y,
        width: params.coordSys.width,
        height: params.coordSys.height
      }
    );
    return (
      rectShape && {
        type: 'rect',
        transition: ['shape'],
        shape: rectShape,
        style: api.style()
      }
    );
  }

  ganttChart.setOption({
    // 提示框
    tooltip: {
      // 自定义提示信息
      formatter: function (params) {
        // params为当前点击图形元素的数据信息的对象
        let name = params.data.releaseUserName;
        let planStartDate = params.value[1];
        let planEndDate = params.value[2] === '9999-12-31 24:00' ? '永久' : params.value[2];
        let planName = params.data.infoName;
        let planType = params.data.releaseOpportunityType;
        return (
          '发布人：' +
          name +
          '<br/><div style="display:flex;align-items: center;">' +
          '发布名称：' +
          '<div style="width:530px;white-space:pre-wrap; ">' +
          planName +
          '</div></div><br/>' +
          '发布类型：' +
          planType +
          '<br/>' +
          '发布时间：' +
          planStartDate +
          ' 至 ' +
          planEndDate
        );
      }
    },
    dataZoom: [
      //   横向使用滚动条
      {
        filterMode: 'weakFilter',
        type: 'slider', // 有单独的滑动条，用户在滑动条上进行缩放或漫游。inside是直接可以是在内部拖动显示
        show: true, // 是否显示 组件。如果设置为 false，不会显示，但是数据过滤的功能还存在。
        xAxisIndex: [0], // 此处表示控制第一个xAxis，设置 dataZoom-slider 组件控制的 x轴 可是已数组[0,2]表示控制第一，三个；xAxisIndex: 2 ，表示控制第二个。yAxisIndex属性同理
        bottom: 50, // 距离底部的距离
        handleSize: '0px',
        handleStyle: {
          color: '#666',
          borderColor: '#fff'
        },
        axisPointer: {
          handle: {
            show: false,
            color: '#000'
          }
        },
        startValue: Date.parse(`${dataTime.value} 08:00`),
        endValue: Date.parse(`${dataTime.value} 16:01`),
        // minValueSpan: Date.parse(`${dataTime.value} 01:00`), // 放大到最少几个
        // maxValueSpan:
        fillerColor: 'rgba(0,0,0,0.10)',
        backgroundColor: '#fff',
        borderColor: '#fff',
        labelFormatter: '',
        height: '6',
        width: '90%',
        left: '100',
        showDetail: false,
        maxValueSpan: 49 * 1000 * 10 * 60,
        minValueSpan: 49 * 1000 * 10 * 60
      },
      // 纵向使用滚动条
      {
        type: 'slider',
        zoomLock: true,
        show: true,

        handleSize: 0,
        yAxisIndex: [0], // 设置组件控制的y轴
        right: '0', // 距离左侧的距离 可以使百分比，也可以是像素 left: '30'（30像素）
        labelFormatter: '',
        // height: '50',
        width: '6',
        startValue: 0, // 从头开始。
        endValue: 3, // 最多4个
        minValueSpan: 3, // 放大到最少几个
        maxValueSpan: 3 // 缩小到最多几个
        // start: 0,
        // end: parseInt(400 / data.length)
      },
      {
        type: 'inside',
        id: 'insideY',
        yAxisIndex: 0,
        zoomOnMouseWheel: false,
        moveOnMouseMove: true,
        moveOnMouseWheel: true
      }
    ],
    // 图表宽高
    grid: {
      show: true,
      top: 50,
      bottom: 90,
      left: 100,
      right: 20,
      backgroundColor: '#fff',
      borderWidth: 0
    },
    // 图例
    // legend: {
    //   bottom: 0,
    //   left: '100'
    //   //   padding: [50, 50, 50, 0]
    //   //   x: 'left',
    //   //   y: 'bottom'
    // },
    // x轴
    xAxis: {
      type: 'time',
      position: 'bottom',
      axisLine: {
        show: false
      },
      axisPointer: {
        handle: {
          show: false,
          color: '#000'
        }
      },
      axisTick: {
        alignWithLabel: true
      },
      // minInterval: 60 * 1000 * 60,
      axisLabel: {
        color: '#666666',
        inside: false,
        align: 'center'
      }
    },
    // Y轴
    yAxis: {
      data: categories,
      inverse: true, // 让y轴数据逆向
      axisTick: {
        show: false // 去除刻度线
      },
      // min: 0,
      // max: 4,
      axisLabel: {
        verticalAlign: 'top',
        color: '#999999', // 文本颜色
        interval: 0,
        margin: 70,
        textStyle: {
          align: 'left',
          baseline: 'middle'
        }
      },
      axisLine: {
        show: false // 去除轴线
      },
      splitLine: {
        show: true, // 显示线
        lineStyle: {
          type: 'dotted',
          color: '#E1DDDD' // 分割线颜色
        }
      }
    },
    // 数据
    series: [
      {
        type: 'custom',
        // 使用自定义的图形元素
        // eslint-disable-next-line no-undef
        renderItem: renderItem,
        name: '计划工期',
        itemStyle: {
          // 透明度
          opacity: 0.8
          //   color: '#E4B778'
        },
        encode: {
          // 将维度1和维度2的数据映射到x轴
          x: [1, 2],
          // 将维度0的数据映射到y轴
          y: 0
        },
        data: data
      },
      // 这个系列并没有太大作用，也没有给它设置data，只是为了通过这个系列，显示图例(legend)而已
      {
        type: 'custom',
        name: '实际工期',
        itemStyle: {
          // 透明度
          opacity: 0.8
          //   color: '#2076ED'
        },
        renderItem() {
          console.log('1');
        }
      }
    ]
  });
}

onMounted(() => {
  getEcharts();
  window.onresize = function () {
    // 自适应大小
    ganttChart && ganttChart.resize();
  };
});
const dataList = ref([]); // 数据列表
// 获取echarts实例
function getEcharts() {
  const params = {
    id: route.query.id,
    recallTime: dataTime.value
  };
  releaseSchedule(params).then(res => {
    const data = res.data.data;
    dataList.value = res.data.data;
    initCharts(data);
  });
}
</script>
<style lang="less" scoped>
.schedule-box {
  // padding: 13px 120px 24px 120px;
  padding-bottom: 20px;
  background: #f2f2f2;
  min-height: 100%;
  height: auto;
  min-width: 1200px;
  .breadcrumb {
    width: 1200px;
    margin: 0 auto 14px;
  }
  .schedule {
    width: 1200px;
    margin: 0 auto;
  }
}
/deep/ .micro-ant-card-body {
  height: 750px !important;
}
/deep/ .micro-app[name='info-system'] .micro-ant-card-bordered {
  border: none;
}
.schedule {
  // padding: 13px 120px 24px 120px;
  // padding: 50px 120px 24px;
  // height: 100vh;
  white-space: nowrap;
  .header-title {
    white-space: nowrap;
    font-size: 16px;
    font-family: Source Han Sans CN, Source Han Sans CN-Regular;
    color: #222222;
  }
  .schedule-flex {
    display: flex;
    justify-content: space-between;
    .schedule-time {
      width: 300px;
      height: 400px;
      border: 1px solid #d9d9d9;
      border-radius: 4px;
      /deep/.micro-ant-btn-text {
        color: #c2c2c2;
      }
      /deep/.micro-ant-btn-text:hover {
        color: rgba(0, 0, 0, 0.85);
      }
    }
    .gantt-chart {
      .no-list {
        height: 400px;
        display: flex;
        justify-content: center;
        align-items: center;
      }
      flex: 1;
      border: 1px solid #d9d9d9;
      border-radius: 4px;
      margin-left: 24px;
      height: 690px;
      overflow: hidden;
      .title-top {
        display: flex;
        padding: 24px 24px 23px 29px;
        .header-title {
          white-space: nowrap;
          font-size: 16px;
          font-family: Source Han Sans CN, Source Han Sans CN-Regular;
          color: #222222;
        }
        .icon-arrow {
          color: #c2c2c2;
          margin-right: 16px;
        }
        .ifont-wid-Calendar_icon_month_left {
          cursor: pointer;
        }
        .ifont-wid-Calendar_icon_month_left:hover {
          color: rgba(0, 0, 0, 0.85);
        }
        .ifont-wid-Calendar_icon_month_right:hover {
          color: rgba(0, 0, 0, 0.85);
        }
        .ifont-wid-Calendar_icon_month_left--disabled {
          cursor: not-allowed !important;
        }
        .ifont-wid-Calendar_icon_month_right {
          margin-left: 20px;
          cursor: pointer;
        }
      }
    }
    .right-gantt {
      padding: 0 24px 145px;
    }
    .legend {
      height: 185px;
      overflow-y: auto;
      display: flex;
      flex-wrap: wrap;
      // width: 900px;
      margin-top: 1px;
      .boxs {
        display: flex;
        margin-bottom: 8px;
        height: 43px;
        margin-bottom: 16px;
        width: 248px;
      }
      .color {
        width: 20px;
        height: 14px;
        border-radius: 4px;
        margin: 4px 0 0 27px;
      }
      .content {
        margin-left: 55px;
        margin-top: -16px;
        .person {
          font-size: 14px;
          font-weight: 400;
          color: #666666;
          width: 98px;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
        }
        .release-name {
          font-size: 14px;
          font-weight: 400;
          color: #666666;
          width: 152px;
          white-space: nowrap;
          text-overflow: ellipsis;
          overflow: hidden;
        }
      }
    }
    /*定义了滚动条整体样式；*/
    .legend::-webkit-scrollbar {
      height: 10px !important;
      width: 6px !important;
    }

    /*定义了滚动条滑块的样式*/
    .legend::-webkit-scrollbar-thumb {
      border-radius: 0;
      //   border-style: dashed;
      background-color: rgba(0, 0, 0, 0.1);
      border-color: #e2242400;
      border-width: 1.5px;
      background-clip: padding-box;
    }
    /*定义了轨道的样式*/
    .legend::-webkit-scrollbar-track {
      /*滚动条里面轨道*/
      -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.1);
      border-radius: 10px;
      background: #ededed;
      height: 22px !important;
    }
    .legend::-webkit-scrollbar-thumb:hover {
      background: rgba(157, 165, 183, 0.7);
    }
  }
}
/deep/ .micro-ant-btn:focus {
  background: rgba(0, 0, 0, 0.028) !important;
  border-color: transparent !important;
}
/deep/ .micro-ant-btn:active {
  background: rgba(0, 0, 0, 0.028) !important;
  border-color: transparent !important;
}
/deep/ .micro-ant-btn:hover {
  background: rgba(0, 0, 0, 0.028) !important;
  border-color: transparent !important;
}
/deep/ .micro-ant-btn-text {
  line-height: 33px !important;
}
.micro-ant-btn-text {
  line-height: 33px !important;
}
/deep/.ifont-wid-Calendar_icon_month_right:hover {
  font-size: 18px;
}
/deep/.ifont-wid-Calendar_icon_month_left:hover {
  font-size: 18px;
}
/deep/ .title-top {
  align-items: center !important;
}
.title-top {
  align-items: center !important;
}
/deep/ .micro-ant-popover-inner-content {
  width: 360px;
}
</style>
